package com.bestcem.xm.txtanls.controller;

import cn.hutool.core.lang.Validator;
import com.bestcem.xm.common.core.constant.Constants;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.component.security.annotation.AuthIgnore;
import com.bestcem.xm.txtanls.dao.AnalysisProjectDao;
import com.bestcem.xm.txtanls.entity.pojo.ProjectDO;
import com.bestcem.xm.txtanls.enums.AnalysisStatusEnum;
import com.bestcem.xm.txtanls.enums.IndustryCodeEnum;
import com.bestcem.xm.txtanls.enums.TrainStatusEnum;
import com.bestcem.xm.txtanls.grpc.client.TxtanlsUserGrpcService;
import com.bestcem.xm.txtanls.service.AnalysisProjectService;
import com.bestcem.xm.txtanls.service.AsyncTaskService;
import com.bestcem.xm.txtanls.service.TrainModelService;
import com.bestcem.xm.txtanls.service.dto.analysis.AnalysisProjectDTO;
import com.bestcem.xm.txtanls.service.dto.user.IndustryDTO;
import com.bestcem.xm.txtanls.service.dto.user.OrgInfoDTO;
import com.bestcem.xm.txtanls.util.AnalysisUtil;
import com.bestcem.xm.txtanls.util.SampleUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

import static com.bestcem.xm.common.core.constant.Constants.ONE;

/**
 * 创建默认项目
 *
 * @author jy.zhao
 * @version 1.0
 * @date 2021/12/9 10:32
 **/
@Api(tags = "文本分析项目")
@RestController
@RequestMapping(value = "/txtanls", produces = MediaType.APPLICATION_JSON_VALUE)
@Slf4j
public class TempController {

    @Value("${app.txtanls.copy-sample.default-org-code:catering}")
    private String oldOrgCode;

    @Resource
    private SampleUtil sampleUtil;

    @Resource
    private AnalysisProjectDao analysisProjectDao;

    @Resource
    private AsyncTaskService asyncTaskService;

    @Resource
    private AnalysisUtil analysisUtil;

    @Resource
    private AnalysisProjectService analysisProjectService;

    @Resource
    private TxtanlsUserGrpcService txtanlsUserGrpcService;

    @Resource
    private TrainModelService trainModelService;


    @ApiOperation(value = "文本分析夜间训练")
    @GetMapping(value = "/projects/analysis")
    @AuthIgnore
    public XmResultJson<AnalysisProjectDTO> analysisProject(@RequestParam(value = "project_id") String projectId) {

        ProjectDO project = analysisProjectDao.findById(projectId);
        if (Validator.isNull(project)) {
            return XmResultJson.fail(4, "没有找到项目");
        }
        ServiceResult<Object> serviceResult = asyncTaskService.trainTask(project);
        if (!serviceResult.isSuccess()) {
            inactiveTrainFailedHandler(projectId, "null", serviceResult.getMsg(), null);
        }


        return XmResultJson.success();
    }

    @GetMapping(value = "/project/test")
    @AuthIgnore
    public XmResultJson<Object> initSample() {
        OrgInfoDTO oldOrgInfo = txtanlsUserGrpcService.getOrgInfoByOrgCodeOrId(oldOrgCode, null);
        String id = oldOrgInfo.getId();
        sampleUtil.initAnalysisProjectForUse(id);

        return XmResultJson.success();
    }

    @GetMapping(value = "/project/delete")
    @AuthIgnore
    public XmResultJson<Object> deleteProject(@RequestParam("id") String projectId) {
        analysisProjectService.deleteProject(projectId);
        return XmResultJson.success();

    }

    /**
     * 所有母环境从餐饮母环境复制一次示例项目
     *
     * @param projectName
     * @return
     */
    @GetMapping(value = "/project/sample/name")
    @AuthIgnore
    public XmResultJson<Object> updateSampleProjectName(@RequestParam(value = "project_name", required = false) String projectName) {
        if (StringUtils.isNotBlank(projectName)) {
            sampleUtil.updateProjectName(projectName);
            return XmResultJson.success();
        }
        projectName = "【示例】文本分析项目";
        sampleUtil.updateProjectName(projectName);

        return XmResultJson.success();
    }

    /**
     * 所有母环境从餐饮母环境复制一次示例项目
     *
     * @param orgCode
     * @return
     */
    @GetMapping(value = "/projects/copy")
    @AuthIgnore
    public XmResultJson<Object> parentOrgCopy(@RequestParam(value = "org_code", required = false) String orgCode) {
        if (StringUtils.isNotBlank(orgCode)) {
            sampleUtil.parentOrgCopy(orgCode);
            return XmResultJson.success();
        }
        // 各个母母环境的orgCode，只可以跑脚本使用，orgCode后面有可能会变
        String[] parentOrgCode = {"hotel",
                "mall",
                "internet",
                "property",
                "medicare",
                "retail",
                "3c",
                "scenic",
                "finance",
                "auto",
                "beauty"};
        for (String oldOrgCode : parentOrgCode) {
            sampleUtil.parentOrgCopy(oldOrgCode);
        }
        return XmResultJson.success();
    }


    /**
     * 训练任务失败处理
     *
     * @param projectId 项目id
     * @param jobName   任务名
     * @param errorMsg  错误信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/5 11:17
     */
    private void inactiveTrainFailedHandler(String projectId, String jobName, String errorMsg, Exception e) {
        // 更新项目状态
        int i = analysisUtil.updateProjectStatus(projectId, AnalysisStatusEnum.INACTIVE);
        if (i != ONE) {
            log.error("[Txtanls] {} 失败任务更新项目状态失败", projectId);
        }
        // 更新训练状态
        int result = analysisProjectDao.updateAnalysisProjectProgress(projectId, TrainStatusEnum.FINISHED, Constants.PROGRESS_FINISHED);
        if (result != ONE) {
            log.error("[Txtanls] {} 失败任务更新训练状态失败", projectId);
        }
        if (Objects.isNull(e)) {
            log.error("[Txtanls] {}-{} 增量训练失败; ErrorMsg: {}", jobName, projectId, errorMsg);
        } else {
            log.error("[Txtanls] {}-{} 增量训练失败; ErrorMsg: {}", jobName, projectId, errorMsg, e);
        }
    }


    @GetMapping(value = "/project/model/id")
    @AuthIgnore
    public XmResultJson<IndustryDTO> setIndustryId() {

        analysisProjectService.setProjectModelId();

        return XmResultJson.success();
    }

    @GetMapping(value = "/project/model/sample")
    @AuthIgnore
    public XmResultJson<Long> setSample() {
        String defaultModelId = trainModelService.getDefaultModelId(IndustryCodeEnum.DIET.getIndex());
        Long updateCount = analysisProjectDao.updateSampleModelId(defaultModelId);

        return XmResultJson.success(updateCount);
    }

}
